package com.layblog.utils;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import org.springframework.util.StringUtils;

import java.beans.PropertyEditorSupport;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Pattern;


/**
 * 类描述：时间操作定义类
 *
 * @Author: Jacklin
 * @Date:2020-12-8 12:15:03
 * @Version 1.0
 */
public class DateUtils extends PropertyEditorSupport {

    /**
     * yyyy-MM-dd
     */
    public static final SimpleDateFormat date_sdf = new SimpleDateFormat("yyyy-MM-dd");
    /**
     * MM-dd
     */
    public static final SimpleDateFormat date_month_day_sdf = new SimpleDateFormat("MM-dd");
    /**
     * yyyy-MM
     */
    public static final SimpleDateFormat date_month_sdf = new SimpleDateFormat("yyyy-MM");
    /**
     * 每月的开始时间
     */
    public static final SimpleDateFormat str_date_sdf = new SimpleDateFormat("yyyy-MM-01 00:00:00");
    /**
     * 每月的结束时间
     */
    public static final SimpleDateFormat end_date_sdf = new SimpleDateFormat("yyyy-MM-31 23:59:59");
    /**
     * yyyyMMdd
     */
    public static final SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyyMMdd");
    /**
     * yyyy年MM月dd日
     */
    public static final SimpleDateFormat date_sdf_wz = new SimpleDateFormat("yyyy年MM月dd日");
    /**
     * yyyy-MM-dd HH:mm
     */
    public static final SimpleDateFormat time_sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    // 各种时间格式
    /**
     * yyyyMMddHHmmss
     */
    public static final SimpleDateFormat yyyymmddhhmmss = new SimpleDateFormat("yyyyMMddHHmmss");
    /**
     * yyyyMMddHHmmssSSS
     */
    public static final SimpleDateFormat yyyymmddhhmmssSSS = new SimpleDateFormat("yyyyMMddHHmmssSSS");
    /**
     * HH:mm
     */
    public static final SimpleDateFormat short_time_sdf = new SimpleDateFormat("HH:mm");
    /**
     * yyyy-MM-dd HH:mm:ss
     */
    public static final SimpleDateFormat datetimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    /**
     * MM
     */
    public static final SimpleDateFormat month_sdf = new SimpleDateFormat("MM");
    // 以毫秒表示的时间
    private static final long DAY_IN_MILLIS = 24 * 3600 * 1000;
    private static final long HOUR_IN_MILLIS = 3600 * 1000;
    private static final long MINUTE_IN_MILLIS = 60 * 1000;
    private static final long SECOND_IN_MILLIS = 1000;
    /**
     * 开始日期的前缀
     */
    public static String dateStr = "%s%s%s%-%s%%s%-01 00:00:00";
    /**
     * 结束日期的前缀
     */
    public static String dateEnd = "%s%s%s%-%s%%s%-31 23:59:59";

    // 指定模式的时间格式
    private static SimpleDateFormat getSDFormat(String pattern) {
        return new SimpleDateFormat(pattern);
    }

    /**
     * 当前日历，这里用中国时间表示
     *
     * @return 以当地时区表示的系统当前日历
     */
    public static Calendar getCalendar() {
        return Calendar.getInstance();
    }

    /**
     * 指定毫秒数表示的日历
     *
     * @param millis 毫秒数
     * @return 指定毫秒数表示的日历
     */
    public static Calendar getCalendar(long millis) {
        Calendar cal = Calendar.getInstance();
        // --------------------cal.setTimeInMillis(millis);
        cal.setTime(new Date(millis));
        return cal;
    }

    // -------------------- getDate，各种方式获取的Date --------------------

    /**
     * 当前日期
     *
     * @return 系统当前时间，格式：Sun Apr 11 16:40:37 CST 2021
     */
    public static Date getDate() {
        return new Date();
    }

    /**
     * 指定毫秒数表示的日期
     *
     * @param millis 毫秒数
     * @return 指定毫秒数表示的日期
     */
    public static Date getDate(long millis) {
        return new Date(millis);
    }

    /**
     * 时间戳转换为字符串
     *
     * @param time
     * @return
     */
    public static String timestampToStr(Timestamp time) {
        Date date = null;
        if (null != time) {
            date = new Date(time.getTime());
        }
        return date2Str(date_sdf);
    }

    /**
     * 6      * 时间戳转换成日期格式字符串
     * 7      * @param seconds 精确到秒的字符串
     * 8      * @param formatStr
     * 9      * @return
     * 10
     */
    public static String timeStamp2Date(String seconds, String format) {
        if (seconds == null || seconds.isEmpty() || seconds.equals("null")) {
            return "";
        }
        if (format == null || format.isEmpty()) {
            format = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(new Date(Long.valueOf(seconds)));
    }

    /**
     * 字符串转换时间戳
     *
     * @param str
     * @return
     */
    public static Timestamp str2Timestamp(String str) {
        Date date = str2Date(str, date_sdf);
        return new Timestamp(date.getTime());
    }

    /**
     * 字符串转换成日期
     *
     * @param str
     * @param sdf
     * @return
     */
    public static Date str2Date(String str, SimpleDateFormat sdf) {
        if (null == str || "".equals(str)) {
            return null;
        }
        Date date = null;
        try {
            date = sdf.parse(str);
            return date;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 日期转换为字符串
     *
     * @param date_sdf 日期格式
     * @return 字符串
     */
    public static String date2Str(SimpleDateFormat date_sdf) {
        Date date = getDate();
        if (null == date) {
            return null;
        }
        return date_sdf.format(date);
    }

    /**
     * 格式化时间
     *
     * @param date
     * @param format
     * @return
     */
    public static String dateFormat(String date, String format) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        Date _date = null;
        try {
            _date = simpleDateFormat.parse(date);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return simpleDateFormat.format(_date);
    }

    /**
     * 日期转换为字符串
     *
     * @param date     日期
     * @param date_sdf 日期格式
     * @return 字符串
     */
    public static String date2Str(Date date, SimpleDateFormat date_sdf) {
        if (null == date) {
            return null;
        }
        return date_sdf.format(date);
    }

    /**
     * 日期转换为字符串
     *
     * @param format 日期格式
     * @return 字符串
     */
    public static String getDate(String format) {
        Date date = new Date();
        if (null == date) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }

    /**
     * 指定毫秒数的时间戳
     *
     * @param millis 毫秒数
     * @return 指定毫秒数的时间戳
     */
    public static Timestamp getTimestamp(long millis) {
        return new Timestamp(millis);
    }

    /**
     * 以字符形式表示的时间戳
     *
     * @param time 毫秒数
     * @return 以字符形式表示的时间戳
     */
    public static Timestamp getTimestamp(String time) {
        return new Timestamp(Long.parseLong(time));
    }

    /**
     * 系统当前的时间戳
     *
     * @return 系统当前的时间戳
     */
    public static Timestamp getTimestamp() {
        return new Timestamp(System.currentTimeMillis());
    }

    /**
     * 当前时间，格式 yyyy-MM-dd HH:mm:ss
     *
     * @return 当前时间的标准形式字符串
     */
    public static String now() {
        return datetimeFormat.format(getCalendar().getTime());
    }

    /**
     * 指定日期的时间戳
     *
     * @param date 指定日期
     * @return 指定日期的时间戳
     */
    public static Timestamp getTimestamp(Date date) {
        return new Timestamp(date.getTime());
    }

    /**
     * 指定日历的时间戳
     *
     * @param cal 指定日历
     * @return 指定日历的时间戳
     */
    public static Timestamp getCalendarTimestamp(Calendar cal) {
        return new Timestamp(cal.getTime().getTime());
    }

    // ------------------ getMillis，各种方式获取的Millis -------------------------

    /**
     * 系统时间的毫秒数
     *
     * @return 系统时间的毫秒数
     */
    public static long getMillis() {
        return System.currentTimeMillis();
    }

    /**
     * 指定日历的毫秒数
     *
     * @param cal 指定日历
     * @return 指定日历的毫秒数
     */
    public static long getMillis(Calendar cal) {
        return cal.getTime().getTime();
    }

    /**
     * 指定日期的毫秒数
     *
     * @param date 指定日期
     * @return 指定日期的毫秒数
     */
    public static long getMillis(Date date) {
        return date.getTime();
    }

    /**
     * 指定时间戳的毫秒数
     *
     * @param ts 指定时间戳
     * @return 指定时间戳的毫秒数
     */
    public static long getMillis(Timestamp ts) {
        return ts.getTime();
    }

    /**
     * 获取时间字符串
     */
    public static String getDataString(SimpleDateFormat formatStr) {
        return formatStr.format(getCalendar().getTime());
    }

    // ------------------ formatDate，将日期按照一定的格式转化为字符串 -------------------

    /**
     * 默认方式表示的系统当前日期，具体格式：年-月-日
     *
     * @return 默认日期按“年-月-日“格式显示
     */
    public static String formatDate() {
        return date_sdf.format(getCalendar().getTime());
    }

    /**
     * 默认方式表示的系统当前日期，具体格式：yyyy-MM-dd HH:mm:ss
     *
     * @return 默认日期按“yyyy-MM-dd HH:mm:ss“格式显示
     */
    public static String formatDateTime() {
        return datetimeFormat.format(getCalendar().getTime());
    }

    /**
     * 获取时间字符串，返回格式：2021-04-11 16:53:42
     */
    public static String getDateString(SimpleDateFormat formatStr) {
        return formatStr.format(getCalendar().getTime());
    }

    /**
     * 指定日期的默认显示，具体格式：年-月-日
     *
     * @param cal 指定的日期
     * @return 指定日期按“年-月-日“格式显示
     */
    public static String formatDate(Calendar cal) {
        return date_sdf.format(cal.getTime());
    }

    /**
     * 指定日期的默认显示，具体格式：年-月-日
     *
     * @param date 指定的日期
     * @return 指定日期按“年-月-日“格式显示
     */
    public static String formatDate(Date date) {
        return date_sdf.format(date);
    }

    /**
     * 指定毫秒数表示日期的默认显示，具体格式：年-月-日
     *
     * @param millis 指定的毫秒数
     * @return 指定毫秒数表示日期按“年-月-日“格式显示
     */
    public static String formatDate(long millis) {
        return date_sdf.format(new Date(millis));
    }

    /**
     * 默认日期按指定格式显示
     *
     * @param pattern 指定的格式
     * @return 默认日期按指定格式显示
     */
    public static String formatDate(String pattern) {
        return getSDFormat(pattern).format(getCalendar().getTime());
    }

    /**
     * 指定日期按指定格式显示
     *
     * @param cal     指定的日期
     * @param pattern 指定的格式
     * @return 指定日期按指定格式显示
     */
    public static String formatDate(Calendar cal, String pattern) {
        return getSDFormat(pattern).format(cal.getTime());
    }

    /**
     * 指定日期按指定格式显示
     *
     * @param date    指定的日期
     * @param pattern 指定的格式
     * @return 指定日期按指定格式显示
     */
    public static String formatDate(Date date, String pattern) {
        return getSDFormat(pattern).format(date);
    }

    // --------------------- formatTime，将日期按照一定的格式转化为字符串 ---------------------

    /**
     * 默认方式表示的系统当前日期，具体格式：年-月-日 时：分
     *
     * @return 默认日期按“年-月-日 时：分“格式显示
     */
    public static String formatTime() {
        return time_sdf.format(getCalendar().getTime());
    }

    /**
     * 指定毫秒数表示日期的默认显示，具体格式：年-月-日 时：分
     *
     * @param millis 指定的毫秒数
     * @return 指定毫秒数表示日期按“年-月-日 时：分“格式显示
     */
    public static String formatTime(long millis) {
        return time_sdf.format(new Date(millis));
    }

    /**
     * 指定日期的默认显示，具体格式：年-月-日 时：分
     *
     * @param cal 指定的日期
     * @return 指定日期按“年-月-日 时：分“格式显示
     */
    public static String formatTime(Calendar cal) {
        return time_sdf.format(cal.getTime());
    }

    /**
     * 指定日期的默认显示，具体格式：年-月-日 时：分
     *
     * @param date 指定的日期
     * @return 指定日期按“年-月-日 时：分“格式显示
     */
    public static String formatTime(Date date) {
        return time_sdf.format(date);
    }

    // ------------------ formatShortTime，将日期按照一定的格式转化为字符串 --------------------

    /**
     * 默认方式表示的系统当前日期，具体格式：时：分
     *
     * @return 默认日期按“时：分“格式显示
     */
    public static String formatShortTime() {
        return short_time_sdf.format(getCalendar().getTime());
    }

    /**
     * 指定毫秒数表示日期的默认显示，具体格式：时：分
     *
     * @param millis 指定的毫秒数
     * @return 指定毫秒数表示日期按“时：分“格式显示
     */
    public static String formatShortTime(long millis) {
        return short_time_sdf.format(new Date(millis));
    }

    /**
     * 指定日期的默认显示，具体格式：时：分
     *
     * @param cal 指定的日期
     * @return 指定日期按“时：分“格式显示
     */
    public static String formatShortTime(Calendar cal) {
        return short_time_sdf.format(cal.getTime());
    }

    /**
     * 指定日期的默认显示，具体格式：时：分
     *
     * @param date 指定的日期
     * @return 指定日期按“时：分“格式显示
     */
    public static String formatShortTime(Date date) {
        return short_time_sdf.format(date);
    }

    // ////////////////////////////////////////////////////////////////////////////
    // parseDate
    // parseCalendar
    // parseTimestamp
    // 将字符串按照一定的格式转化为日期或时间
    // ////////////////////////////////////////////////////////////////////////////

    /**
     * 根据指定的格式将字符串转换成Date 如输入：2003-11-19 11:20:20将按照这个转成时间
     *
     * @param src     将要转换的原始字符窜
     * @param pattern 转换的匹配格式
     * @return 如果转换成功则返回转换后的日期
     * @throws ParseException
     */
    public static Date parseDate(String src, String pattern) throws ParseException {
        return getSDFormat(pattern).parse(src);

    }

    /**
     * 根据指定的格式将字符串转换成Date 如输入：2003-11-19 11:20:20将按照这个转成时间
     *
     * @param src     将要转换的原始字符窜
     * @param pattern 转换的匹配格式
     * @return 如果转换成功则返回转换后的日期
     * @throws ParseException
     */
    public static Calendar parseCalendar(String src, String pattern) throws ParseException {

        Date date = parseDate(src, pattern);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal;
    }

    public static String formatAddDate(String src, String pattern, int amount) throws ParseException {
        Calendar cal;
        cal = parseCalendar(src, pattern);
        cal.add(Calendar.DATE, amount);
        return formatDate(cal);
    }

    /**
     * 根据指定的格式将字符串转换成Date 如输入：2003-11-19 11:20:20将按照这个转成时间
     *
     * @param src     将要转换的原始字符窜
     * @param pattern 转换的匹配格式
     * @return 如果转换成功则返回转换后的时间戳
     * @throws ParseException
     */
    public static Timestamp parseTimestamp(String src, String pattern) throws ParseException {
        Date date = parseDate(src, pattern);
        return new Timestamp(date.getTime());
    }

    // ---------------------- dateDiff，计算两个日期之间的差值 ---------------------

    /**
     * 计算两个时间之间的差值，根据标志的不同而不同
     *
     * @param flag   计算标志，表示按照年/月/日/时/分/秒等计算
     * @param calSrc 减数
     * @param calDes 被减数
     * @return 两个日期之间的差值
     */
    public static int dateDiff(char flag, Calendar calSrc, Calendar calDes) {

        long millisDiff = getMillis(calSrc) - getMillis(calDes);
        if (flag == 'y') {
            return (calSrc.get(Calendar.YEAR) - calDes.get(Calendar.YEAR));
        }
        if (flag == 'd') {
            return (int) (millisDiff / DAY_IN_MILLIS);
        }
        if (flag == 'h') {
            return (int) (millisDiff / HOUR_IN_MILLIS);
        }
        if (flag == 'm') {
            return (int) (millisDiff / MINUTE_IN_MILLIS);
        }
        if (flag == 's') {
            return (int) (millisDiff / SECOND_IN_MILLIS);
        }
        return 0;
    }

    public static long minDiff(Date beginTime, Date endTime) {
        if (oConvertUtils.isEmpty(beginTime) || oConvertUtils.isEmpty(endTime)) {
            return 0;
        }
        long between = (endTime.getTime() - beginTime.getTime()) / 1000;
        long min = between / 60;
        return min;
    }

    public static int getYear() {
        GregorianCalendar calendar = new GregorianCalendar();
        calendar.setTime(getDate());
        return calendar.get(Calendar.YEAR);
    }

    /**
     * 获取当前月
     *
     * @author: huangw
     * @since: 2021/10/7 15:41
     **/
    public static int getMonth() {
        Calendar cal = Calendar.getInstance();
        int month = cal.get(Calendar.MONTH) + 1;
        return month;
    }

    /**
     * 获取当前天
     *
     * @author: huangw
     * @since: 2021/10/7 15:41
     **/
    public static int getDay() {
        Calendar cal = Calendar.getInstance();
        int day = cal.get(Calendar.DATE);
        return day;
    }

    /**
     * 获取当前时间 多少天之前 的时间 ，格式：2021-04-11 17:17:23
     *
     * @param dayNum
     * @author jacklin
     * @since 2021-04-11 18:01:45
     */
    public static String getFewDaysBeforeOfThisCurrentTime(Integer dayNum) {
        return DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now().minus(Period.ofDays(dayNum)));
    }

    // --------------------- Java8 minus和plus 对日期进行加减操作 ------------------------

    /**
     * 获取当前时间 多少天之后 的时间 ，格式：2021-04-11 17:17:23
     *
     * @param dayNum
     * @author jacklin
     * @since 2021-04-11 18:03:22
     */
    public static String getFewDaysAfterOfThisCurrentTime(Integer dayNum) {
        return DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now().plus(Period.ofDays(dayNum)));
    }

    /**
     * 获取当前时间 多少个月之前 的时间 ，格式：2021-04-11 17:17:23
     *
     * @param monthNum
     * @author jacklin
     * @since 2021-04-11 18:05:58
     */
    public static String getFewMonthsBeforeOfThisCurrentTime(Integer monthNum) {
        return DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now().minusMonths(monthNum));
    }

    /**
     * 获取当天开始时间
     *
     * @author: jacklin
     * @since: 2020/10/29 14:43
     **/
    public static String getDayStartTimeStr() {
        LocalDateTime todayStart = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);//当天零点
        String startTime = todayStart.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        return startTime;
    }

    /**
     * 获取当天结束时间
     *
     * @author: jacklin
     * @since: 2020/10/29 14:43
     **/
    public static String getDayEndTimeStr() {
        LocalDateTime todayStart = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);//当天23:59:59点
        String endTime = todayStart.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        return endTime;
    }

    /**
     * Description: 判断一个时间是否在一个时间段内，不包括闭区间，期望包括闭区间看方法：isEffectiveDate
     *
     * @param nowTime   当前时间 </br>
     * @param beginTime 开始时间 </br>
     * @param endTime   结束时间 </br>
     */
    public static boolean belongCalendar(Date nowTime, Date beginTime, Date endTime) {
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(beginTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        return date.after(begin) && date.before(end);
    }

    /**
     * 得到几天前的时间
     *
     * @param date
     * @param day
     * @return
     */

    public static Date getDateBefore(Date date, int day) {
        Calendar now = Calendar.getInstance();
        now.setTime(date);
        now.set(Calendar.DATE, now.get(Calendar.DATE) - day);
        return now.getTime();
    }

    /**
     * 得到几天后的时间
     *
     * @param d
     * @param day
     * @return
     */
    public static Date getDateAfter(Date d, int day) {
        Calendar now = Calendar.getInstance();
        now.setTime(d);
        now.set(Calendar.DATE, now.get(Calendar.DATE) + day);
        return now.getTime();
    }

    /**
     * 两个时间之间差多少小时
     *
     * @return
     * @paramstartTime
     * @paramendTime
     */
    public static long getHoursBetween(String startTime, String endTime) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        long seconds = 0L;
        try {
            Date startDate = formatter.parse(startTime);
            long msStart = startDate.getTime();
            Date endDate = formatter.parse(endTime);
            long msEnd = endDate.getTime();
            seconds = (msEnd - msStart) / (1000 * 60 * 60);
        } catch (ParseException e) {
            e.printStackTrace();

        }
        return seconds;
    }

    /**
     * 判断两个时间是否存在交集
     *
     * @author: jacklin
     * @since: 2021/7/15 10:43
     **/
    public static boolean isDateTimeCross(String startDate1, String endDate1, String startDate2, String endDate2) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date leftStartDate = null;
        Date leftEndDate = null;
        Date rightStartDate = null;
        Date rightEndDate = null;
        try {

            if (oConvertUtils.isEmpty(startDate1) || oConvertUtils.isEmpty(endDate1) || oConvertUtils.isEmpty(startDate2) || oConvertUtils.isEmpty(endDate2)) {
                return false;
            }

            leftStartDate = format.parse(startDate1);
            leftEndDate = format.parse(endDate1);
            rightStartDate = format.parse(startDate2);
            rightEndDate = format.parse(endDate2);

        } catch (ParseException e) {
            return false;
        }

        return ((leftStartDate.getTime() >= rightStartDate.getTime()) && leftStartDate.getTime() < rightEndDate.getTime()) ||
                ((leftStartDate.getTime() > rightStartDate.getTime()) && leftStartDate.getTime() <= rightEndDate.getTime()) ||
                ((rightStartDate.getTime() >= leftStartDate.getTime()) && rightStartDate.getTime() < leftEndDate.getTime()) ||
                ((rightStartDate.getTime() > leftStartDate.getTime()) && rightStartDate.getTime() <= leftEndDate.getTime());
    }

    /**
     * 判断两个时间是否存在交集
     *
     * @param startDateOne 第一个时间段的开始时间
     * @param endDateOne   第一个时间段的结束时间
     * @param startDateTwo 第二个时间段的开始时间
     * @param endDateTwo   第二个时间段的结束时间
     * @author: jacklin
     * @date: 2022/3/14 18:36
     **/
    public static Boolean IsInterSection(Date startDateOne, Date endDateOne, Date startDateTwo, Date endDateTwo) {
        Date maxStartDate = startDateOne;
        if (maxStartDate.before(startDateTwo)) {
            maxStartDate = startDateTwo;
        }

        Date minEndDate = endDateOne;
        if (endDateTwo.before(minEndDate)) {
            minEndDate = endDateTwo;
        }
        if (maxStartDate.before(minEndDate) || (maxStartDate.getTime() == minEndDate.getTime())) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获取某个时间X分钟之后的时间点
     *
     * @author: jacklin
     * @since: 2021/8/13 10:14
     **/
    public static Date getAfterDateOfMin(Date baseDate, int min) {
        long time = min * 60 * 1000;
        Date afterDate = new Date(baseDate.getTime() + time);   //min分钟后的时间
        return afterDate;
    }

    /**
     * 获取某个字符串时间X分钟之后的字符串时间点
     *
     * @author: huangw
     * @since: 2021/10/25 10:14
     **/
    public static String getAfterStrDateOfMin(String stringDate, int min) {
        String afterDate = "";
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d1 = null;
        try {
            d1 = df.parse(stringDate);
            Calendar cal = Calendar.getInstance();
            cal.setTime(d1);
            cal.add(Calendar.MINUTE, min);
            Date d2 = cal.getTime();
            afterDate = df.format(d2);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return afterDate;
    }

    /**
     * 获取两个时间段内的所有日期，日期可跨年
     *
     * @author: jacklin
     * @since: 2021/8/26 18:18
     **/
    public static List<String> getBetweenDate(String begin, String end) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        List<String> betweenList = new ArrayList<String>();
        try {
            Calendar startDay = Calendar.getInstance();
            startDay.setTime(format.parse(begin));
            startDay.add(Calendar.DATE, -1);
            while (true) {
                startDay.add(Calendar.DATE, 1);
                Date newDate = startDay.getTime();
                String newDateStr = format.format(newDate);
                betweenList.add(newDateStr);
                if (end.equals(newDateStr)) {
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return betweenList;
    }

    /**
     * 获取某一月的所有周的日期段(周一到周日)，包括日期和星期几
     *
     * @author: jacklin
     * @since: 2021/9/3 17:08
     **/
    public static List<Map<String, Object>> GetAllWeekDateListSegmentsOfMonth(String yearMonth) {
        List<Map<String, Object>> mapList = Lists.newArrayList();
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
        sdf1.setLenient(false);
        SimpleDateFormat sdf2 = new SimpleDateFormat("EEE");
        for (int i = 1; i < 32; i++) {
            Map<String, Object> map = new HashMap<>();
            try {
                Date date = sdf1.parse(yearMonth + "-" + i);
                map.put("date", sdf1.format(date));
                map.put("weekDay", sdf2.format(date));
                mapList.add(map);
                //System.out.println(sdf1.format(date) + " : " + sdf2.format(date));
            } catch (ParseException e) {
                //do nothing
            }
        }
        return mapList;
    }

    /**
     * 获取 获取某年某月 所有日期（yyyy-mm-dd格式字符串）
     *
     * @author: jacklin
     * @since: 2021/9/3 17:17
     **/
    public static List<String> getMonthFullDay(int year, int month) {
        SimpleDateFormat dateFormatYYYYMMDD = new SimpleDateFormat("yyyy-MM-dd");
        List<String> fullDayList = new ArrayList<>(32);
        // 获得当前日期对象
        Calendar cal = Calendar.getInstance();
        cal.clear();// 清除信息
        cal.set(Calendar.YEAR, year);
        // 1月从0开始
        cal.set(Calendar.MONTH, month - 1);
        // 当月1号
        cal.set(Calendar.DAY_OF_MONTH, 1);
        int count = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        for (int j = 1; j <= count; j++) {
            fullDayList.add(dateFormatYYYYMMDD.format(cal.getTime()));
            cal.add(Calendar.DAY_OF_MONTH, 1);
        }
        return fullDayList;
    }

    /**
     * 获取当前月份的开始和结束日期，比如2021-10月，返回2021-10-01和2021-10-31
     *
     * @author: jacklin
     * @since: 2021/10/18 17:59
     **/
    public static JSONObject getFirstAndLastDateOfCurrentMonth() {
        JSONObject jsonObject = new JSONObject();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, 0);
        //设置为1号,当前日期既为本月第一天
        c.set(Calendar.DAY_OF_MONTH, 1);
        String firstDate = format.format(c.getTime());

        //获取当前月最后一天
        Calendar ca = Calendar.getInstance();
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        String lastDate = format.format(ca.getTime());

        jsonObject.put("firstMonthDate", firstDate);
        jsonObject.put("lastMonthDate", lastDate);
        return jsonObject;
    }

    /**
     * 获取下一个月的最后一天，返回yyyy-MM-dd格式
     *
     * @author: jacklin
     * @since: 2021/10/28 11:46
     **/
    public static String getPerLastDayOfMonth() {
        SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, 1);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        return dft.format(calendar.getTime());
    }

    /**
     * 获取上个月的第一天，返回yyyy-MM-dd格式
     *
     * @author: jacklin
     * @since: 2021/10/28 11:46
     **/
    public static String getLastMinMonthDate() {
        SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MONTH, -1);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        return dft.format(calendar.getTime());
    }

    /**
     * 判断当前时间是否在[startTime, endTime]区间，注意时间格式要一致
     *
     * @param nowTime   当前时间
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return
     * @author jqlin
     */
    public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
        if (nowTime.getTime() == startTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return true;
        }

        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获取给定时间与当前系统时间的差值（以毫秒为单位）
     *
     * @author GaoHuanjie
     */
    public static long getTimeDifferenceBetweenSystemTimeAndParamTime(String paramTime) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String systemTime = DateUtils.now();// 获取当前时间
        long difference = 0;
        try {
            Date systemDate = dateFormat.parse(systemTime);
            Date paramDate = dateFormat.parse(paramTime);
            difference = paramDate.getTime() - systemDate.getTime();
//            System.out.println("系统时间：" + systemTime + "，给定时间：" + paramTime 	+ "，给定时间与当前系统时间的差值（以毫秒为单位）：" + difference + "毫秒");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return difference;
    }

    public static boolean isValidDate(String inputDate, String format) {
        // 指定日期格式为四位年/两位月份/两位日期，注意yyyy/MM/dd区分大小写；
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        try {
            if (dateFormat.format(dateFormat.parse(inputDate)).equalsIgnoreCase(inputDate)) {
                System.out.println("OK");
                System.out.println(dateFormat.format(dateFormat.parse(inputDate)));
                return true;
            } else {
                System.out.println("Err");
                System.out.println(dateFormat.format(dateFormat.parse(inputDate)));
                return false;
            }
        } catch (Exception ex) {
            System.out.println("Err");
            return false;
        }
    }

    /**
     * 判断字符串是不是Integer
     *
     * @param str
     * @return true OR false
     */
    public static boolean isInteger(String str) {
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }

    /**
     * 获得当前日期 yyyy-MM-dd HH:mm:ss
     *
     * @return 2021-10-28 16:39:38
     * @author huangw
     */
    public static String getCurrentTime() {
        // 小写的hh取得12小时，大写的HH取的是24小时
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new Date();
        return df.format(date);
    }

    public static void main(String[] args) {
        String startTime1 = "2022-03-14 09:00:00";
        String endTime1 = "2022-03-14 10:00:00";
        String startTime2 = "2022-03-14 10:00:00";
        String endTime2 = "2022-03-14 11:40:00";
        System.out.println(IsInterSection(DateUtils.str2Date(startTime1, DateUtils.datetimeFormat),
                DateUtils.str2Date(endTime1, DateUtils.datetimeFormat),
                DateUtils.str2Date(startTime2, DateUtils.datetimeFormat),
                DateUtils.str2Date(endTime2, DateUtils.datetimeFormat)));
    }

    /**
     * String类型 转换为Date, 如果参数长度为10 转换格式 "yyyy-MM-dd" 如果参数长度为19 转换格式 "yyyy-MM-dd HH:mm:ss"
     *
     * @param text String类型的时间值
     */
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        if (StringUtils.hasText(text)) {
            try {
                if (text.indexOf(":") == -1 && text.length() == 10) {
                    setValue(DateUtils.date_sdf.parse(text));
                } else if (text.indexOf(":") > 0 && text.length() == 19) {
                    setValue(DateUtils.datetimeFormat.parse(text));
                } else {
                    throw new IllegalArgumentException("Could not parse date, date format is error ");
                }
            } catch (ParseException ex) {
                IllegalArgumentException iae = new IllegalArgumentException("Could not parse date: " + ex.getMessage());
                iae.initCause(ex);
                throw iae;
            }
        } else {
            setValue(null);
        }
    }

}
